package com.qiqijuice.sales;

import net.miginfocom.swt.MigLayout;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;

public class ProductView extends Composite {
	Tree tree;
	Table table;

	MigLayout layout;
	SashForm sashRoot;
	SashForm sashRight;
	TabFolder tabFolder;
	
	ProductCRUDView productCRUD;
	CategoryCRUDView categoryCRUD;
	
	public ProductView(Composite frame) {
		super(frame, SWT.None);
		
		FormLayout fl = new FormLayout();
		fl.marginWidth = 5;
		fl.marginHeight = 5;
		setLayout(fl);

		Composite btnGroup = new Composite(this,SWT.None);
		
		RowLayout rl = new RowLayout();
		rl.marginWidth = 5;
		rl.marginHeight = 5;
		btnGroup.setLayout(rl);
		
		FormData fd = new FormData();
		fd.top = new FormAttachment(0,0);
		fd.left = new FormAttachment(0,0);
		fd.right = new FormAttachment(100,0);
		btnGroup.setLayoutData(fd);
		
		Button btn = new Button(btnGroup, SWT.PUSH);
		btn.setText("New Category");
		btn.addSelectionListener(new SelectionAdapter() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				createCategory();
			}
			
		});
		
		btn = new Button(btnGroup, SWT.PUSH);
		btn.setText("Delete Category");

		btn = new Button(btnGroup, SWT.PUSH);
		btn.setText("New Product");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				createProduct();
			}			
		});
		
		btn = new Button(btnGroup, SWT.PUSH);
		btn.setText("Delete Product");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				deleteProduct();
			}
		});

		sashRoot = new SashForm(this, SWT.HORIZONTAL);
		fd = new FormData();
		fd.top = new FormAttachment(btnGroup,5);
		fd.left = new FormAttachment(0,0);
		fd.right = new FormAttachment(100,0);
		fd.bottom = new FormAttachment(100,0);
		sashRoot.setLayoutData(fd);
		
		tree = new Tree(sashRoot, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		TreeItem treei = new TreeItem(tree, SWT.None);
		treei.setText("Categories");
		treei.setExpanded(true);
		tree.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				refreshProductData((ProductCategory) e.item.getData());
				viewSelectedProductCategory(false);
				viewSelectedProduct();
			}
			
		});
		sashRight = new SashForm(sashRoot, SWT.VERTICAL);
		
		table = new Table(sashRight, SWT.BORDER);
		table.setLinesVisible (true);
		table.setHeaderVisible (true);
		String[] titles = {"Name", "Price", "Description"};
		int[] widths = {150, 50, 400};
		for (int i = 0; i<titles.length; ++i) {
			TableColumn tc = new TableColumn(table, SWT.NONE);
			tc.setText(titles[i]);
			tc.setWidth(widths[i]);
		}
		table.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				viewSelectedProduct();
			}
			
		});
		
		tabFolder = new TabFolder(sashRight, SWT.NONE);
		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("Product Properties");
		productCRUD = new ProductCRUDView(tabFolder, SWT.NONE);
		tabItem.setControl(productCRUD);
		
		tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("Product Category Properties");
		categoryCRUD = new CategoryCRUDView(tabFolder, SWT.NONE);
		tabItem.setControl(categoryCRUD);
		
		sashRoot.setWeights(new int[]{1,5});
		sashRight.setWeights(new int[]{4,2});
	}	
	
	void refreshCategoryData() {
		
		// get the "root" item holder and clear content
		TreeItem root = tree.getItem(0);
		root.removeAll();
		
		// fill in all categories
		ProductCategory pc = new ProductCategory();
		ObjectContainer oc = Db4oContainerFactory.getDB();
		ObjectSet<ProductCategory> result = oc.queryByExample(pc);
		for (ProductCategory cat : result) {
			TreeItem ti = new TreeItem(root, SWT.NONE);
			ti.setText(cat.getName());
			ti.setData(cat);
		}
		
		root.setExpanded(true);
	}
			
	public void productCategoryChanged() {
		refreshCategoryData();
	}
	
	void createCategory() {
		String defName = "New Category ";
		boolean free = false;
		ProductCategory pilot = new ProductCategory(null, null);
		int i  = 0;
		while (!free) {
			pilot.setName(defName + (++i));
			ObjectContainer oc = Db4oContainerFactory.getDB();
			ObjectSet<ProductCategory> result = oc.queryByExample(pilot);
			free = result.isEmpty();
		}
		
		pilot.setDesc("Default Description");
		ObjectContainer oc = Db4oContainerFactory.getDB();
		oc.store(pilot);
		
		refreshCategoryData();
		
		if (selectProductCategory(pilot))
			viewSelectedProductCategory(true);
	}
	
	TreeItem searchTree(TreeItem root, ProductCategory pc) {
		if (root.getData() == pc)
			return root;
		else {
			for (TreeItem ti : root.getItems()) {
				TreeItem result = searchTree(ti, pc);
				if (result != null)
					return result;
			}
		}
		
		return null;
	}
	
	TreeItem searchTree(Tree root, ProductCategory pc) {
		for (TreeItem ti: root.getItems()) {
			TreeItem result = searchTree(ti, pc);
			if (result != null)
				return result;
		}
		
		return null;
	}
	
	boolean selectProductCategory(ProductCategory pc) {
		TreeItem ti = searchTree(tree, pc);
		
		if (ti != null) {
			tree.select(ti);
			return true;
		}
		else
			return false;
	}
	
	void viewSelectedProductCategory(boolean selectCategoryView) {
		if (tree.getSelectionCount() == 1) {
			if (selectCategoryView)
				tabFolder.setSelection(1);
			
			ProductCategory pc = (ProductCategory) tree.getSelection()[0].getData();
			categoryCRUD.viewCategory(pc);
		}
	}
	
	void createProduct() {
		if (tree.getSelectionCount() == 1) {
			TreeItem ti = tree.getSelection()[0];
			if (ti.getData() != null) {
				ProductCategory pc = (ProductCategory) ti.getData();
				
				String defName = "New Product ";
				boolean free = false;
				Product pilot = new Product(null, null, 0, pc);

				ObjectContainer oc = Db4oContainerFactory.getDB();
				
				int i  = 0;
				while (!free) {
					pilot.setName(defName + (++i));
					ObjectSet<Product> result = oc.queryByExample(pilot);
					free = result.isEmpty();
				}

				pilot.setDesc("Default Description");
				oc.store(pilot);

				refreshProductData(pc);
				
				if (selectProduct(pilot))
					viewSelectedProduct();
			}
		}
	}
	
	boolean selectProduct(Product p) {
		for (int i=0; i<table.getItemCount(); ++i) {
			if (table.getItem(i).getData() == p) {
				table.select(i);
				return true;
			}
		}
		return false;
	}

	void deleteProduct() {
		if (table.getSelectionCount() == 1) {
			TableItem tbi = table.getSelection()[0];
			Product p = (Product) tbi.getData();

			ObjectContainer oc = Db4oContainerFactory.getDB();

			if (p != null) {
				oc.delete(p);
				refreshProductData();
			}
		}
		
	}
	
	void refreshProductData() {
		if (tree.getSelectionCount() == 1) {
			ProductCategory pc = (ProductCategory) tree.getSelection()[0].getData();
			refreshProductData(pc);
		}
	}
	
	@SuppressWarnings("serial")
	void refreshProductData(final ProductCategory pc) {
		table.removeAll();

		ObjectContainer oc = Db4oContainerFactory.getDB();

		if (pc != null) {
			ObjectSet<Product> result = oc.query(new Predicate<Product>() {

				@Override
				public boolean match(Product p) {
					return p.getCategory() == pc;
				}
			});
			
			for (Product p : result) {
				TableItem tbi = new TableItem(table, SWT.NONE);
				tbi.setText(0, p.getName());
				tbi.setText(2, p.getDesc());
				tbi.setText(1, ""+p.getPrice());
				tbi.setData(p);
			}
		}
	}

	void viewSelectedProduct() {
		if (table.getSelectionCount() == 1) {
			tabFolder.setSelection(0);
			Product p = (Product) table.getSelection()[0].getData();
			productCRUD.viewProduct(p);
		}
		else
			productCRUD.viewProduct(null);
	}
}
